Technote PR 16 | March 1992 |
Changes since March 1992: Corrected the Vulcan-like "THPring" typo to correctly read "THPrint," and changed a comment in the code to mean what I originally meant.
Like many Printing Manager calls, PrJobMerge is implemented by the currently chosen printer driver. This makes sense after consideration--since the printer driver may store job-specific information anywhere in the print record, only the printer driver can correctly merge this into a destination print record.
The LaserWriter driver's implementation of PrJobMerge has a few bugs
in versions 7.0 and 7.1.
Historically, PrJobMerge hasn't worked correctly in the LaserWriter driver. The driver does not correctly merge all job-related data (like the number of copies requested) into the destination print record, so printing multiple copies of multiple documents from the Finder isn't really possible with the LaserWriter driver.
The only possible workaround is to present a different job dialog for each document to be printed, but this isn't recommended--especially since the job dialog doesn't tell you which document you're about to print.
As if this wasn't enough excitement for one driver, in versions 7.0 and 7.1 of the LaserWriter driver PrJobMerge actually manages to destroy all the job-specific information in the source print record after it doesn't copy it into the destination print record.
There is a workaround for this problem--make a copy of the source print record and pass the copy to PrJobMerge. If you pass the copy to PrJobMerge, you can just replace PrJobMerge with your own routine that makes a copy, merges it into the destination, and disposes of the copy. This will work for all printer drivers, although it's necessary only with version 7.0 of the LaserWriter driver.
Such a procedure might look like this in Pascal:
PROCEDURE NewPrJobMerge(hPrintSrc,hPrintDst: THPrint); VAR copyError: OSErr; hPrintTemp: THPrint; BEGIN hPrintTemp := hPrintSrc; {make our own copy of the print record handle} copyError := HandToHand(Handle(hPrintTemp)); PrSetError(copyError); {so we can get it later} IF copyError = noErr THEN BEGIN {hPrintTemp is now a copy of the original source record} PrJobMerge(hPrintTemp,hPrintDst); {This messes up hPrintTemp, but we don't care} END; {if copyError = noErr} IF hPrintTemp <> NIL THEN DisposHandle(Handle(hPrintTemp)); {only a copy, remember!} END;
Although the bugs in PrJobMerge in versions 7.0 and 7.1 of the LaserWriter driver make certain kinds of printing multiple documents impossible without device-specific workarounds, we strongly encourage you not to implement such code. Any code that tries to replicate the function of PrJobMerge must by nature depend on how the LaserWriter driver stores information in the print record, and this is a Bad Thing. The road to Compatibility Hell is paved with good intentions.
If you write your code as described in this Note, it will behave properly when
the bug is fixed without change on your part. If you go overboard trying to
write your own PrJobMerge function, your application is a prime
candidate for compatibility problems.
Further Reference: